package com.strong.utils.jpa.service;

import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.springframework.data.domain.Page;
import org.springframework.transaction.TransactionStatus;

import java.util.List;

/**
 * 自定义数据库处理Service.
 *
 * @param <E> 实体类泛型
 * @param <M> 模型类泛型
 * @author Simen
 * @version 1.0
 */
public interface StrongService<E, M> {

    /**
     * 根据实体类返回模型类，ignoreProperties为需设置为控制的属性名
     *
     * @param entity                实体类
     * @param strsIncludeProperties 包含的字段数组
     * @return 模型类
     */
    M getModel(@NotNull final E entity, final String... strsIncludeProperties);

    /**
     * 根据实体类返回模型类，ignoreProperties为需设置为控制的属性名
     *
     * @param entity                实体类
     * @param ignoreNullValue       是否忽略空值，当源对象的值为null时，true: 忽略而不注入此值，false: 注入null
     * @param strsIncludeProperties 包含的字段数组
     * @return 模型类
     */
    M getModel(@NotNull final E entity, @NotNull final boolean ignoreNullValue, final String... strsIncludeProperties);

    /**
     * 根据实体类队列返回模型类队列，ignoreProperties为需设置为控制的属性名
     *
     * @param listE                 实体类记录集
     * @param strsIncludeProperties 包含的字段数组
     * @return 模型类记录集
     */
    List<M> getModelList(@NotEmpty final List<E> listE, final String... strsIncludeProperties);

    /**
     * 根据实体类队列返回模型类队列，ignoreProperties为需设置为控制的属性名
     *
     * @param listE                 实体类记录集
     * @param ignoreNullValue       是否忽略空值，当源对象的值为null时，true: 忽略而不注入此值，false: 注入null
     * @param strsIncludeProperties 包含的字段数组
     * @return 模型类记录集
     */
    List<M> getModelList(@NotEmpty final List<E> listE, @NotNull final boolean ignoreNullValue, final String... strsIncludeProperties);

    /**
     * 根据实体类的Page 返回模型类的Page
     *
     * @param page                  实体类分页对象
     * @param strsIncludeProperties 包含的字段数组
     * @return
     */
    Page<M> getModelPage(@NotEmpty final Page<E> page, final String... strsIncludeProperties);


    /**
     * 根据实体类的Page 返回模型类的Page
     *
     * @param page                  实体类分页对象
     * @param ignoreNullValue       是否忽略空值，当源对象的值为null时，true: 忽略而不注入此值，false: 注入null
     * @param strsIncludeProperties 包含的字段数组
     * @return
     */
    Page<M> getModelPage(@NotEmpty final Page<E> page, @NotNull final boolean ignoreNullValue, final String... strsIncludeProperties);

    /**
     * 清空缓存
     */
    void cacheEvict();

    /**
     * 返回事务的状态，用于手工提交事务
     *
     * @return the transaction status
     */
    TransactionStatus getTransactionStatus();
}
